package com.beta.cust.bind.datasync.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.beta.cat.service.RedissonService;
import com.beta.cust.bind.datasync.constant.BusinessConstant;
import com.beta.cust.bind.datasync.constant.CacheConstans;
import com.beta.cust.bind.datasync.dto.WeixinCorpListDTO;
import com.beta.cust.bind.datasync.mapper.entity.AuthCorpInfo;
import com.beta.cust.bind.datasync.service.ISyncWechatWorkCorpInfo;
import com.beta.cust.bind.datasync.service.IWechatWorkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author：wangjaing
 * @Date：2024/4/10 20:24
 */
@Service
@Slf4j
public class SyncWechatWorkCorpInfoImpl implements ISyncWechatWorkCorpInfo {

    @Autowired
    private RedissonService redissonService;

    @Autowired
    private IWechatWorkService wechatWorkService;

    @Autowired
    private AuthCorpInfoServiceImpl corpInfoService;

    @Override
    public void syncWechatWorkCorp(String corpId) {
        String lockKey = String.format(CacheConstans.SYNC_CORP_INFO, corpId);
        try {
            if (redissonService.tryLock(lockKey, CacheConstans.WAIT_TIME)) {//一直锁到同步结束
                LocalDateTime syncCorpTime = LocalDateTime.now();
                //循环结束标识 1表示拉取完毕，0表示数据没有拉取完
                int ending = 0;
                //分页游标，再下次请求时填写以获取之后分页的记录，如果已经没有更多的数据则返回空
                String cursor = "";
                while (ending == 0) {
                    //调用企微接口 获取下游企业列表
                    WeixinCorpListDTO dto = wechatWorkService.corpList(false, corpId, cursor);
                    List<WeixinCorpListDTO.CropDetailDTO> detailDTOS = dto.getCorpList();
                    //未返回下游企业列表终止循环
                    if (CollectionUtils.isEmpty(detailDTOS)) {
                        break;
                    }
                    syncCorpList(detailDTOS);
                    ending = dto.getEnding();
                    cursor = dto.getNextCursor();
                }
                //全部下游企业同步结束后，更改更新时间在任务启动之前的数据为软删除
                afterDeleteCorp(syncCorpTime);
            } else {
                log.warn("syncWechatWorkCorp 当前已有定时任务运行中...");
            }
        } catch (Exception e) {
            log.error("syncWechatWorkCorp error：{}", e.getMessage(), e);
        } finally {
            redissonService.unlock(lockKey);
        }
    }

    private void afterDeleteCorp(LocalDateTime syncCorpTime) {
        try {
            //避免数据太少 快速结束 误删除
            Thread.sleep(2000);
            AuthCorpInfo corpInfo = new AuthCorpInfo();
            corpInfo.setDelFlag(BusinessConstant.IS_DEL_FLAG);
            corpInfoService.update(corpInfo, new LambdaQueryWrapper<AuthCorpInfo>().lt(AuthCorpInfo::getUpdateTime, Timestamp.valueOf(syncCorpTime)));
        } catch (Exception e) {
            log.error("afterDeleteCorp error:{}", e.getMessage(), e);
        }

    }

    private void syncCorpList(List<WeixinCorpListDTO.CropDetailDTO> detailDTOS) {
        //1.获取所有的corpId集合
        Set<String> corpIdList = new HashSet<>();
        for (WeixinCorpListDTO.CropDetailDTO dto : detailDTOS) {
            corpIdList.add(dto.getCorpId());
        }
        //2.根据corpId查询数据库
        List<AuthCorpInfo> existList = corpInfoService.list(new LambdaQueryWrapper<AuthCorpInfo>().in(AuthCorpInfo::getCorpId, corpIdList));
        List<AuthCorpInfo> addList = new ArrayList<>();
        List<AuthCorpInfo> updateList = new ArrayList<>();
        //3.1数据库全部数据都不存在 则直接新增
        if (CollectionUtils.isEmpty(existList)) {
            addList = getCorpList(detailDTOS);
        } else {
            List<String> existCorpIdList = existList.stream().map(AuthCorpInfo::getCorpId).collect(Collectors.toList());
            Map<String, AuthCorpInfo> corpInfoMap = existList.stream().collect(Collectors.toMap(AuthCorpInfo::getCorpId, a -> a));
            //3.2数据库存在则新增 数据库不存在则新增
            for (WeixinCorpListDTO.CropDetailDTO dto : detailDTOS) {
                if (existCorpIdList.contains(dto.getCorpId())) {
                    updateList.add(getCorp(dto, corpInfoMap.get(dto.getCorpId())));
                } else {
                    AuthCorpInfo corpInfo = new AuthCorpInfo();
                    addList.add(getCorp(dto, corpInfo));
                }
            }
        }
        if (!CollectionUtils.isEmpty(addList)) {
            corpInfoService.saveBatch(addList);
        }
        if (!CollectionUtils.isEmpty(updateList)) {
            corpInfoService.updateBatchById(updateList);
        }
    }

    private List<AuthCorpInfo> getCorpList(List<WeixinCorpListDTO.CropDetailDTO> detailDTOS) {
        List<AuthCorpInfo> corpInfos = new ArrayList<>();
        for (WeixinCorpListDTO.CropDetailDTO dto : detailDTOS) {
            AuthCorpInfo corpInfo = new AuthCorpInfo();
            corpInfo = getCorp(dto, corpInfo);
            corpInfos.add(corpInfo);
        }
        return corpInfos;
    }

    private AuthCorpInfo getCorp(WeixinCorpListDTO.CropDetailDTO dto, AuthCorpInfo corpInfo) {
        corpInfo.setCorpId(dto.getCorpId());
        corpInfo.setCorpName(dto.getCorpName());
        corpInfo.setAgentId(dto.getAgentId());
        corpInfo.setDelFlag(BusinessConstant.IS_NOT_DEL_FLAG);
        corpInfo.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
        return corpInfo;
    }
}

